// 对axios进行二次封装
// 封装的目标： 让后边用起来更轻松
// 封装的内容：
// 1. 设置基地址
// 2. 请求拦截器
// 3. transformResponse:大数处理

import axios from 'axios'
// 在普通的.js模块中去使用vuex中的数据：正常import
import store from '../store/index.js'
// 引入大数处理包
import JSONBig from 'json-bigint'
// 引入路由
import router from '@/router/auth.js'

// 用自己的配置，通过axios.create 创建一个实例
// instance上面具备的方法与axios的方法是一样的
// 后端服务器1
const instance = axios.create({
  // 如果用了它，则所有的接口地址中的/app要去掉
  // 测试帐号：13912345678
  baseURL: 'http://toutiao-app.itheima.net/',
  // baseURL: 'http://ttapi.research.itcast.cn',
  // transformResponse是axios提供的一个工具： 用来在获取后端数据之后，先进行处理，
  // 再通过promise返回给axios的调用者
  transformResponse: [function (data) {
    // console.log(data)
    // 由于后端返回的数据有出现大数问题（文章编号）,这里使用json-bigint处理一下
    try {
      // 优先使用JSONBig转一下
      return JSONBig.parse(data)
    } catch (err) {
      return data
    }
  }]
  // baseURL: 'http://api-toutiao-web.itheima.net'
  // timeout: 1000,
  // headers: {'X-Custom-Header': 'foobar'}
})

// 添加请求拦截器
instance.interceptors.request.use(function (config) {
  config.url = config.url.replace('/app/', '/')
  // 在发送请求之前做些什么:
  // 获取vuex中的token
  const token = store.state.tokenInfo.token
  // 1. 如果有token就带上
  if (token) {
    // 用模板字符串，向当前请求中，添加token
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器
instance.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  return response
}, async function (error) {
  // 对响应错误做点什么
  // 如果是401错误，则统一来处理
  if (error.response.status === 401) {
    // 是否有refresh_token,如果没有，说明你根本就没有登陆，应该直接回到登陆页
    const refreshToken = store.state.tokenInfo.refresh_token
    if (refreshToken) {
      // 用refreshToken去发请求，取回新token(再次有两个小时的有效期)
      try {
        // 这次请求并没有用instance，因为它会走请求拦截器，额外添加错误的token
        const res = await axios({
          url: 'http://toutiao-app.itheima.net/v1_0/authorizations',
          method: 'PUT',
          headers: {
            Authorization: `Bearer ${refreshToken}`
          }
        })
        // 更新vuex
        const newToken = res.data.data.token
        store.commit('mSetTokenInfo', {
          token: newToken,
          refresh_token: refreshToken
        })
        // 重发请求
        // 用instance加上本次出错时请配置，再发一次
        // 再次进入请求拦截器，拿到更新到了token
        return instance(error.config)
      } catch (err) {
        store.commit('mSetTokenInfo', {})
        // 更新token 失败 用refresh_token去请求新token时，出错了
        // 可能的原因是refresh_token也过期了，此时，只能去登陆
        router.push('/login?backto=' + encodeURIComponent(router.currentRoute.fullPath))
      }
    } else {
      // 回去登陆页
      console.log('你没有登陆哈，直接回login了')
      // currentRoute: 是router的属性，它表示当前路由
      router.push('/login?backto=' + encodeURIComponent(router.currentRoute.fullPath))
    }
  }
  return Promise.reject(error)
})

// 后端服务器2
const instance2 = axios.create({
  baseURL: 'http://api-toutiao-web.itheima.net'
  // timeout: 1000,
  // headers: {'X-Custom-Header': 'foobar'}
})

// 按需导出
export { instance, instance2 }

// 默认导出intance
export default instance
